/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Services;

import Beans.PermissionsBean;
import Beans.Requests.RequestBean;
import Beans.Requests.UserManagement.UserCreateRequest;
import Beans.Requests.UserManagement.UserRemoveRequest;
import Beans.Requests.SimpleAuthorizationRequest;
import Beans.Requests.UserManagement.UserManagementRequest;
import Beans.Requests.UserManagement.UserModifyRequest;
import Beans.Requests.UserManagement.UserPasswordResetRequest;
import Beans.Requests.UserManagement.UserPermissionsRequest;
import Beans.Responses.UserManagementResponse;
import Beans.UserBean;
import Managers.DatabaseManager;
import Managers.LogsManager;
import Managers.PermissionsManager;
import Managers.SessionsManager;
import Managers.Utilities.DatabaseManipulationResult;
import Managers.Utilities.RequestResponseWrapper;
import Managers.Utilities.ResponseMessagesContainer;
import Utilities.Constants;
import Utilities.ExceptionMessages;
import Utilities.ApplicationException;
import Utilities.Functions;
import Utilities.ParameterNames;
import Utilities.PermissionsConstants;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * This servlet represents the application's Users Management Service. <br><br>
 *
 * This service takes care of the user creation, removal, modification and
 * user permissions management.
 *
 * @author Angel Sanadinov
 */
public class UsersManagementService extends HttpServlet
{
    private LogsManager logsManager = null;                 //logs manager
    private DatabaseManager databaseManager = null;         //database manager
    private SessionsManager sessionsManager = null;         //sessions manager
    private PermissionsManager permissionsManager = null;   //permissions manager
    private String passwordHashingAlgorithm; //algorithm for hashing user passwords
    private String systemCharsetName;        //default system charset

    /**
     * Initializes the service and retrieves all necessary managers.
     *
     * @throws ServletException if an exception occurs that interrupts the servlet's
     *                          normal operation
     *
     * @see HttpServlet#init()
     */
    @Override
    public void init() throws ServletException
    {
        ServletContext context = getServletContext();
        logsManager = (LogsManager)context.getAttribute(Constants.CONTEXT_LOGS_MANAGER);
        databaseManager = (DatabaseManager)context.getAttribute(Constants.CONTEXT_DATABASE_MANAGER);
        sessionsManager = (SessionsManager)context.getAttribute(Constants.CONTEXT_SESSIONS_MANAGER);
        permissionsManager = (PermissionsManager)context.getAttribute(Constants.CONTEXT_PERMISSIONS_MANAGER);
        passwordHashingAlgorithm = context.getInitParameter(ParameterNames.PASSWORD_HASHING_ALGORITHM);
        systemCharsetName = context.getInitParameter(ParameterNames.DEFAULT_CHARSET);
    }

    /**
     * Shuts down the service and cleans up any object references.
     *
     * @see HttpServlet#destroy()
     */
    @Override
    public void destroy()
    {
        //log shutdown of service?
        logsManager = null;
        databaseManager = null;
        sessionsManager = null;
        permissionsManager = null;
    }

    /**
     * Processes a <code>GET</code> request from a client.
     *
     * @param request an HttpServletRequest object that contains the request the
     *                client has made of the servlet
     * @param response an HttpServletResponse object that contains the response
     *                 the servlet sends to the client
     * @throws ServletException if the request for the GET could not be handled
     * @throws IOException if an input or output error is detected when the servlet
     *         handles the GET request
     *
     * @see HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /**
     * Processes a <code>POST</code> request from a client.
     *
     * @param request an HttpServletRequest object that contains the request the
     *                client has made of the servlet
     * @param response an HttpServletResponse object that contains the response
     *                 the servlet sends to the client
     * @throws ServletException if the request for the POST could not be handled
     * @throws IOException if an input or output error is detected when the servlet
     *         handles the POST request
     *
     * @see HttpServlet#doPost(HttpServletRequest, HttpServletResponse)
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }

    /**
     * Processes all <code>GET</code> and <code>POST</code> requests and carries out
     * operations based on requested actions.
     *
     * @param request an HttpServletRequest object that contains the request the
     *                client has made of the servlet
     * @param response an HttpServletResponse object that contains the response
     *                 the servlet sends to the client
     * @throws ServletException if the request could not be handled
     * @throws IOException if an input or output error is detected when the service
     *         handles the request
     */
    private void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        //retrieves the user management request
        UserManagementRequest manageUserRequest =
                (UserManagementRequest)request.getAttribute(ParameterNames.REQUEST_MANAGE_USER);

        //checks that the request is available and is valid
        if(manageUserRequest != null && manageUserRequest.isValid())
        {
            logsManager.logSystemEvent(System.currentTimeMillis(), Constants.LOG_SEVERITY_DEBUG,
                                           "Request: " + manageUserRequest.toString());

            //attempts to authorize the request
            boolean isActionAuthorized = false;
            if(manageUserRequest.getRequestedAction() == PermissionsConstants.ACTION_USER_RESET_OWN_PASSWORD)
                isActionAuthorized = true;//all users can reset their own passwords
            else
                isActionAuthorized = permissionsManager.isActionAuthorized(
                        new SimpleAuthorizationRequest(manageUserRequest.getRequestorId(),
                                                       PermissionsConstants.BASIC_ACTION_MANAGE_USER));

            //<editor-fold defaultstate="collapsed" desc="Action Selection">
            //checks if the request is authorized...
            if(isActionAuthorized)
            {
                //carries out the appropriate action based on the request data
                switch(manageUserRequest.getRequestedAction())
                {
                    //a new user is to be added
                    case PermissionsConstants.ACTION_USER_CREATE:
                    {
                        processResponse(request, actionCreateUser((UserCreateRequest)manageUserRequest));
                    } break;

                    //an existing user is to be modified
                    case PermissionsConstants.ACTION_USER_MODIFY:
                    {
                        processResponse(request, actionModifyUser((UserModifyRequest)manageUserRequest));
                    } break;

                    //an existing user to be removed
                    case PermissionsConstants.ACTION_USER_REMOVE:
                    {
                        processResponse(request, actionRemoveUser((UserRemoveRequest)manageUserRequest));

                    } break;

                    //a user password is to be reset
                    case PermissionsConstants.ACTION_USER_RESET_PASSWORD:
                    case PermissionsConstants.ACTION_USER_RESET_OWN_PASSWORD:
                    {
                        processResponse(request, actionResetPassword((UserPasswordResetRequest)manageUserRequest));
                    } break;

                    //new permissions for a user are to be added
                    case PermissionsConstants.ACTION_USER_CREATE_PERMISSIONS:
                    {
                        processResponse(request, actionCreatePermissions((UserPermissionsRequest)manageUserRequest));
                    } break;

                    //existing permissions for a user are to be removed
                    case PermissionsConstants.ACTION_USER_REMOVE_PERMISSIONS:
                    {
                        processResponse(request, actionRemovePermissions((UserPermissionsRequest)manageUserRequest));
                    } break;

                    //existing permissions for a user are to be modified
                    case PermissionsConstants.ACTION_USER_MODIFY_PERMISSIONS:
                    {
                        processResponse(request, actionModifyPermissions((UserPermissionsRequest)manageUserRequest));
                    } break;

                    default: 
                    {
                        processResponse(request, new UserManagementResponse(false,
                                new ApplicationException(ExceptionMessages.APP_E_INVALID_REQUESTED_ACTION)));
                    } break;
                }
            }
            else
            {
                processResponse(request, new UserManagementResponse(false, 
                        new ApplicationException(ExceptionMessages.APP_E_OPERATION_NOT_ALLOWED)));
            }
            //</editor-fold>
        }
        else
        {
            processResponse(request, new UserManagementResponse(false, 
                    new ApplicationException(ExceptionMessages.APP_E_INVALID_REQUEST)));
        }
    }

    /**
     * Processes all responses going out of the service.
     *
     * @param request an HttpServletRequest object that contains the request the
     *                client has made of the servlet
     * @param response an HttpServletResponse object that contains the response
     *                 the servlet sends to the client
     * @param userResponse user management response object
     * @throws ServletException if the processing of the response could not be handled
     * @throws IOException if an input or output error is detected when the response
     *                     is handled
     */
    private void processResponse(HttpServletRequest request , UserManagementResponse userResponse)
            throws ServletException, IOException
    {
        //retrieves the request object from the session
        RequestBean requestData = (RequestBean)request.getAttribute(ParameterNames.REQUEST_MANAGE_USER);
        request.setAttribute(ParameterNames.REQUEST_MANAGE_USER, null);
        request.setAttribute(ParameterNames.RESPONSE_MANAGE_USER, userResponse);

        //checks if the requested action failed
        if(!userResponse.getRequestResult())
        {
            //the request failed; retrieves the message container and stores the request/response pair
            ResponseMessagesContainer messagesContainer = (ResponseMessagesContainer)
                    request.getSession(false).getAttribute(ParameterNames.SESSION_REQUEST_MESSAGES_OBJECT);

            messagesContainer.put(new RequestResponseWrapper(requestData, userResponse));

            logsManager.logSystemEvent(System.currentTimeMillis(), Constants.LOG_SEVERITY_DEBUG,
                                       "Request execution failed: " + userResponse.getException().toString());
        }
        else
            ;
    }

    /**
     * Creates a new user.
     *
     * @param request user creation request
     * @return a response to the user management request
     */
    private UserManagementResponse actionCreateUser(UserCreateRequest request)
    {
        ApplicationException exception = null; //operation exception
        boolean responseStatus = false; //operation response status

        try
        {
            DatabaseManipulationResult result = null;
            //creation of accounts with higher level than the requestor's is not allowed
            if(sessionsManager.getUserData(request.getRequestorId()).getAccountLevel() < request.getAccountLevel())
            {
                return new UserManagementResponse(false,
                        new ApplicationException(ExceptionMessages.APP_E_OPERATION_NOT_ALLOWED));
            }
            else
            {
                UserBean newUserData =
                        new UserBean(request.getUsername(),
                                     Functions.hashPassword(request.getPassword(), passwordHashingAlgorithm, systemCharsetName),
                                     request.getAccountLevel());
                
                result = databaseManager.insertUser(newUserData);
            }

            //checks that a valid DMR was returned
            if(result != null)
            {
                if(result.wasOperationSuccessful()) //was the operation successful?
                {
                    responseStatus = true;
                    //logs the user creation
                    logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                                    "User " + request.getUsername() + " was created", request.getRequestorId());
                }
                else if(result.getErrorCode() == Constants.SQL_ERROR_ENTRY_EXISTS)
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_USER_EXISTS,
                                                         "(" + request.getUsername() + ")");
                }
                else
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                         "(" + result.getErrorCode() + ")");
                }
            }
            else
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");
            
        }
        catch(Exception e)
        {
            logsManager.logSystemEvent(System.currentTimeMillis(),
                                       Constants.LOG_SEVERITY_ERROR,
                                       e.getMessage());
            exception = new ApplicationException(ExceptionMessages.APP_E_USER_CREATION_FAILED);
            responseStatus = false;
        }

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Modifies an existing user's data.
     *
     * @param request user modification request
     * @return a response to the user management request
     */
    private UserManagementResponse actionModifyUser(UserModifyRequest request)
    {
        ApplicationException exception = null;  //operation exception
        boolean responseStatus = false; //operation response status
        DatabaseManipulationResult result = null; //database operation result

        //sets the account level
        if(request.isAccountLevelSet())
        {
            //a manager is not allowed to elevate own account level
            if(sessionsManager.getUserData(request.getRequestorId()).getAccountLevel() < request.getAccountLevel())
            {
                return new UserManagementResponse(false, 
                        new ApplicationException(ExceptionMessages.APP_E_OPERATION_NOT_ALLOWED));
            }
            else
                result = databaseManager.setUserAccountLevel(request.getAffectedUserId(), request.getAccountLevel());
        }
        else
            ;

        //checks that a valid DMR was returned
        if(result != null)
        {
            if(result.wasOperationSuccessful()) //was the operation successful?
            {
                responseStatus = true;
                //logs the user modification
                logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                                "User " + request.getAffectedUserId() + " was modified", request.getRequestorId());

                //notifies the sessions manager of the change
                sessionsManager.updateUserData(request.getAffectedUserId());
            }
            else if(result.getErrorCode() == Constants.SQL_ERROR_NOT_UPDATED)
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_USER_MODIFICATION_FAILED,
                                                     "(" + request.getAffectedUserId() + ")");
            }
            else
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                     "(" + result.getErrorCode() + ")");
            }
        }
        else
            exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Removes an existing user.
     *
     * @param request user removal request
     * @return a response to the user management request
     */
    private UserManagementResponse actionRemoveUser(UserRemoveRequest request)
    {
        DatabaseManipulationResult result = null;
        ApplicationException exception = null;  //operation exception
        boolean responseStatus = false; //operation response status

        UserBean userData = databaseManager.getUser(request.getAffectedUserId());
        if(userData != null)
        {
            //a manager is not allowed to elevate own account level
            if(sessionsManager.getUserData(request.getRequestorId()).getAccountLevel() < userData.getAccountLevel())
            {
                return new UserManagementResponse(false,
                        new ApplicationException(ExceptionMessages.APP_E_OPERATION_NOT_ALLOWED));
            }
            else //attemtps to remove the user from the database
                result = databaseManager.removeUser(request.getAffectedUserId());


            //checks that a valid DMR was returned
            if(result != null)
            {
                if(result.wasOperationSuccessful()) //was the operation successful?
                {
                    DatabaseManipulationResult permissionsRemovalResult =
                            databaseManager.removeAllUserPermissions(request.getAffectedUserId());
                    if(!permissionsRemovalResult.wasOperationSuccessful())
                    {
                        logsManager.logSystemEvent(System.currentTimeMillis(),
                                Constants.LOG_SEVERITY_WARNING,
                                "Failed to remove permissions for user " + request.getAffectedUserId());
                    }
                    else
                        ;

                    responseStatus = true;
                    //logs the user removal
                    logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                                "User " + request.getAffectedUserId() + " was removed", request.getRequestorId());
                }
                else if(result.getErrorCode() == Constants.SQL_ERROR_NOT_REMOVED)
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_USER_REMOVAL_FAILED,
                                                         "(" + request.getAffectedUserId() + ")");
                }
                else
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                         "(" + result.getErrorCode() + ")");
                }
            }
            else
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");
        }
        else
        {
            exception = new ApplicationException(ExceptionMessages.APP_E_USER_REMOVAL_FAILED,
                                                         "(" + request.getAffectedUserId() + ") does not exist.");
        }

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Resets a user's password.
     *
     * @param request user password reset request
     * @return a response to the user management request
     */
    private UserManagementResponse actionResetPassword(UserPasswordResetRequest request)
    {
        ApplicationException exception = null;  //operation exception

        boolean responseStatus = false; //operation response status
        
        int userId =  request.getAffectedUserId();
        
        try
        {
            //checks if the user is requesting to modify own password
            if(request.getRequestedAction() == PermissionsConstants.ACTION_USER_RESET_OWN_PASSWORD)
            {
                userId = request.getRequestorId(); //sets a new user id
                //retrieves the user's name
                String username = sessionsManager.getUserData(userId).getUsername();

                //attempts to verify the user's credentials
                if(databaseManager.verifyUserCredentials(username,
                        Functions.hashPassword(request.getOldPassword(), passwordHashingAlgorithm, systemCharsetName)) != userId)
                {
                    return new UserManagementResponse(false,
                            new ApplicationException(ExceptionMessages.APP_E_CREDENTIALS_VERIFICATION_FAILED));
                }
                else
                    ;
            }
            else
            {
                //checks if this is an attempt to reset the password of an account with a higher level
                UserBean targetUser = databaseManager.getUser(userId);
                if(targetUser == null || (targetUser.getAccountLevel() >
                        sessionsManager.getUserData(request.getRequestorId()).getAccountLevel()))
                {
                    return new UserManagementResponse(false,
                        new ApplicationException(ExceptionMessages.APP_E_OPERATION_NOT_ALLOWED));
                }
                else
                    ;
            }

            //attempts to reset the user's password
            DatabaseManipulationResult result = 
                    databaseManager.resetUserPassword(userId, Functions.hashPassword(request.getNewPassword(),
                                                                                     passwordHashingAlgorithm,
                                                                                     systemCharsetName));

            //checks that a valid DMR was returned
            if(result != null)
            {
                if(result.wasOperationSuccessful()) //was the operation successful?
                {
                    responseStatus = true;
                    //logs the password reset
                    logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                                "Password reset for user: " + request.getAffectedUserId(), request.getRequestorId());
                }
                else if(result.getErrorCode() == Constants.SQL_ERROR_NOT_UPDATED)
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_USER_PASSWORD_RESET_FAILED,
                                                         "(" + request.getAffectedUserId() + ")");
                }
                else
                {
                    exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                         "(" + result.getErrorCode() + ")");
                }
            }
            else
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");
        }
        catch(Exception e)
        {
            logsManager.logSystemEvent(System.currentTimeMillis(),
                                       Constants.LOG_SEVERITY_ERROR,
                                       e.getMessage());
            exception = new ApplicationException(ExceptionMessages.APP_E_USER_PASSWORD_RESET_FAILED, "(N/A)");
            responseStatus = false;
        }

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Creates new permissions for an existing user.
     *
     * @param request user permissions management request
     * @return a response to the user management request
     */
    private UserManagementResponse actionCreatePermissions(UserPermissionsRequest request)
    {
        ApplicationException exception = null;  //operation exception
        boolean responseStatus = false; //operation response status

        //attempts to add the new permissions to the database
        DatabaseManipulationResult result =
                databaseManager.insertPermissions(new PermissionsBean(request.getAffectedUserId(),
                                                                      request.getServerId(),
                                                                      request.getMachinesPermissions(),
                                                                      request.getMediaPermissions(),
                                                                      request.getNetworksPermissions()));

        //checks that a valid DMR was returned
        if(result != null)
        {
            if(result.wasOperationSuccessful()) //was the operation successful?
            {
                String message = "Added permissions for user " + request.getAffectedUserId()
                                  + " on server " + request.getServerId();
                responseStatus = true;

                //logs the permissions addition
                logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                                message, request.getRequestorId());

                //user needs to logout and login for the new permissions to be recognized
            }
            else if(result.getErrorCode() == Constants.SQL_ERROR_ENTRY_EXISTS)
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_USER_PERMISSIONS_EXIST,
                        request.getAffectedUserId() + " on server " + request.getServerId());
            }
            else
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                     "(" + result.getErrorCode() + ")");
            }
        }
        else
            exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Removes a user's permissions.
     *
     * @param request user permissions management request
     * @return a response to the user management request
     */
    private UserManagementResponse actionRemovePermissions(UserPermissionsRequest request)
    {
        //attemtps to remove the permissions from the database
        DatabaseManipulationResult result = 
                databaseManager.removePermissions(request.getAffectedUserId(), request.getServerId());
        ApplicationException exception = null;  //operation exception
        boolean responseStatus = false; //operation response status

        //checks that a valid DMR was returned
        if(result != null)
        {
            if(result.wasOperationSuccessful()) //was the operation successful?
            {
                String message = "Permissions for user " + request.getAffectedUserId() + " on"
                                   + request.getServerId() + " were removed";
                responseStatus = true;

                //logs the permissions removal
                logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                            message, request.getRequestorId());

                //notifies the sessions manager of the change
                sessionsManager.updateUserPermissions(request.getAffectedUserId(), request.getServerId());
            }
            else if(result.getErrorCode() == Constants.SQL_ERROR_NOT_REMOVED)
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_USER_PERMISSIONS_REMOVAL_FAILED,
                        request.getAffectedUserId() + " on server " + request.getServerId());
            }
            else
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                     "(" + result.getErrorCode() + ")");
            }
        }
        else
            exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");

        return new UserManagementResponse(responseStatus, exception);
    }

    /**
     * Modifies a user's permissions.
     *
     * @param request user permissions management request
     * @return a response to the user management request
     */
    private UserManagementResponse actionModifyPermissions(UserPermissionsRequest request)
    {
        ApplicationException exception = null;  //operation exception
        boolean responseStatus = false; //operation response status

        //attempts to modify the permissions
        DatabaseManipulationResult result =
                databaseManager.updatePermissions(new PermissionsBean(request.getAffectedUserId(),
                                                                      request.getServerId(),
                                                                      request.getMachinesPermissions(),
                                                                      request.getMediaPermissions(),
                                                                      request.getNetworksPermissions()));

        //checks that a valid DMR was returned
        if(result != null)
        {
            if(result.wasOperationSuccessful()) //was the operation successful?
            {
                String message = "Modified permissions for user " + request.getAffectedUserId()
                                  + " on server " + request.getServerId();
                responseStatus = true;

                //logs the permissions removal
                logsManager.log(System.currentTimeMillis(), Constants.LOG_SEVERITY_INFORMATION,
                            message, request.getRequestorId());

                //notifies the sessions manager of the change
                sessionsManager.updateUserPermissions(request.getAffectedUserId(), request.getServerId());
            }
            else if(result.getErrorCode() == Constants.SQL_ERROR_NOT_UPDATED)
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_USER_PERMISSIONS_MODIFICATION_FAILED,
                        request.getAffectedUserId() + " on server " + request.getServerId());
            }
            else
            {
                exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION,
                                                     "(" + result.getErrorCode() + ")");
            }
        }
        else
            exception = new ApplicationException(ExceptionMessages.APP_E_DATABASE_EXCEPTION, "(N/A)");

        return new UserManagementResponse(responseStatus, exception);
    }
}
